(function (zn){

    var __NS = {
        SVG: 'http://www.w3.org/2000/svg',
        HTML: 'http://www.w3.org/1999/xhtml',
        XBL: 'http://www.mozilla.org/xbl',
        XUL: 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'
    };

    /**
     * @class Element
     * @namespace zn.ui.dom
     * @desc The element for dom.
     */
    var DOM = zn.class('zn.ui.dom.DOM', zn.ui.core.Element, {
        partial: true,
        properties: {
            content: {
                set: function (value){
                    var _nodeType = this._dom.nodeType;
                    if(_nodeType === 1){
                        this._dom.innerHTML = value;
                    }
                    else if(_nodeType === 3) {
                        this._dom.textContent = value;
                    }
                },
                get: function (){
                    var _nodeType = this._dom.nodeType;
                    if(_nodeType === 1){
                        return this._dom.innerHTML;
                    }
                    else if(_nodeType === 3) {
                        return this._dom.textContent;
                    }
                }
            },
            value: {
                get: function (){

                },
                set: function (){

                }
            }
        },
        methods: {
            init: function (dom){
                this._dom = this.__parseDom(dom);
                if(!this._dom){
                    throw new Error('The dom of DOM is not exist.');
                }
            },
            bind: function (name, value){
                var _owner = this.owner;
                if(_owner){
                    _owner.let(name, value, _owner, this);
                }

                return this;
            },
            set: function (prop, value) {
                if (this.has(prop)) {
                    this.super(prop, value);
                } else {
                    this.setAttribute(prop, value);
                }

                return true;
            },
            get: function (prop) {
                if (this.has(prop)) {
                    return this.super(prop);
                } else {
                    return this.getAttribute(prop);
                }
            },
            contains: function (target) {
                return this._dom.contains(this.__getTargetDom(target));
            },
            prepend: function (child) {
                var _dom = this._dom,
                    _childDom = this.__getTargetDom(child),
                    _first = _dom.firstChild;
                if (_first) {
                    _dom.insertBefore(_childDom, _first);
                } else {
                    _dom.appendChild(_childDom);
                }

                return this;
            },
            append: function (child) {
                return this._dom.appendChild(this.__getTargetDom(child)), this;
            },
            before: function (ref) {
                var _refNode = this.__getTargetDom(ref),
                    _parentNode = _refNode.parentElement;

                return _parentNode.insertBefore(this._dom, _refNode), this;
            },
            after: function (ref) {
                var _refNode = this.__getTargetDom(ref),
                    _parentNode = _refNode.parentElement,
                    _nextNode = _refNode.nextElementSibling;

                if (_nextNode) {
                    _parentNode.insertBefore(this._dom, _nextNode);
                } else {
                    _parentNode.appendChild(_refNode);
                }

                return this;
            },
            clone: function (isDeep) {
                return new DOM(this._dom.cloneNode(isDeep));
            },
            remove: function () {
                return this._dom.remove(), this;
            },
            first: function () {
                return new DOM(this._dom.firstElementChild);
            },
            last: function () {
                return new DOM(this._dom.lastElementChild);
            },
            previous: function () {
                return new DOM(this._dom.previousElementSibling);
            },
            next: function () {
                return new DOM(this._dom.nextElementSibling);
            },
            parentElement: function () {
                return new DOM(this._dom.parentElement);
            },
            index: function () {
                if (this.parent !== null) {
                    return this.parent.children.indexOf(this);
                } else {
                    return -1;
                }
            },
            child: function (index) {
                return this.children[index];
            },
            dispose: function (){

            },
            __getTargetDom: function (target){
                if(zn.is(target, DOM)){
                    return target._dom;
                }

                return target;
            },
            __parseDom: function (expr){
                if(zn.is(expr, 'string')){
                    if(expr.indexOf('#') !== -1||expr.indexOf('.') !== -1){
                        return document.querySelector(expr);
                    }else {
                        if(expr.indexOf(':')!==-1){
                            var _expr = expr.split(':');
                            return document.createElementNS(__NS[_expr[0].toUpperCase()], _expr[1]);
                        }

                        return document.createElement(expr);
                    }
                }
                else {
                    return expr;
                }
            }
        }
    });

    zn.$ = function (expr, owner){
        var _dom = new DOM(expr);
        return _dom.owner = owner, _dom;
    }

})(zn);
